// Copyright (c) ZeroC, Inc.

namespace Ice.objects;

public sealed class InitialI : Test.InitialDisp_
{
    public InitialI(Ice.ObjectAdapter adapter)
    {
        _adapter = adapter;
        _b1 = new BI();
        _b2 = new BI();
        _c = new CI();
        _d = new DI();

        _b1.theA = _b2; // Cyclic reference to another B
        _b1.theB = _b1; // Self reference.
        _b1.theC = null; // Null reference.

        _b2.theA = _b2; // Self reference, using base.
        _b2.theB = _b1; // Cyclic reference to another B
        _b2.theC = _c; // Cyclic reference to a C.

        _c.theB = _b2; // Cyclic reference to a B.

        _d.theA = _b1; // Reference to a B.
        _d.theB = _b2; // Reference to a B.
        _d.theC = null; // Reference to a C.
    }

    public override void getAll(out Test.B b1, out Test.B b2, out Test.C theC, out Test.D theD, Current current)
    {
        b1 = _b1;
        b2 = _b2;
        theC = _c;
        theD = _d;
    }

    public override Test.CsClass opRenamedClass(Test.CsClass r, Ice.Current current) => r;

    public override Test.B getB1(Ice.Current current) => _b1;

    public override Test.B getB2(Ice.Current current) => _b2;

    public override Test.C getC(Ice.Current current) => _c;

    public override Test.D getD(Ice.Current current) => _d;

    public override Test.K getK(Ice.Current current) => new Test.K(new Test.L("l"));

    public override Ice.Value opValue(Ice.Value v1, out Ice.Value v2, Ice.Current current)
    {
        v2 = v1;
        return v1;
    }

    public override Ice.Value[] opValueSeq(Ice.Value[] v1, out Ice.Value[] v2, Ice.Current current)
    {
        v2 = v1;
        return v1;
    }

    public override Dictionary<string, Ice.Value>
    opValueMap(Dictionary<string, Value> v1, out Dictionary<string, Value> v2, Current current)
    {
        v2 = v1;
        return v1;
    }

    public override void setRecursive(Test.Recursive p, Ice.Current current)
    {
    }

    public override void setCycle(Test.Recursive r, Ice.Current current)
    {
    }

    public override bool acceptsClassCycles(Ice.Current current) => true;

    public override Test.D1 getD1(Test.D1 d1, Ice.Current current) => d1;

    public override void throwEDerived(Ice.Current current) =>
        throw new Test.EDerived(new Test.A1("a1"), new Test.A1("a2"), new Test.A1("a3"), new Test.A1("a4"));

    public override void setG(Test.G theG, Ice.Current current)
    {
    }

    public override Test.Base[] opBaseSeq(Test.Base[] inSeq, out Test.Base[] outSeq, Ice.Current current)
    {
        outSeq = inSeq;
        return inSeq;
    }

    public override Test.Compact getCompact(Ice.Current current) => new Test.CompactExt();

    public override void shutdown(Ice.Current current) => _adapter.getCommunicator().shutdown();

    public override Test.Inner.A
    getInnerA(Ice.Current current) => new Test.Inner.A(_b1);

    public override Test.Inner.Sub.A
    getInnerSubA(Ice.Current current) => new Test.Inner.Sub.A(new Test.Inner.A(_b1));

    public override void throwInnerEx(Ice.Current current) => throw new Test.Inner.Ex("Inner::Ex");

    public override void throwInnerSubEx(Ice.Current current) => throw new Test.Inner.Sub.Ex("Inner::Sub::Ex");

    public override Test.Initial_GetMBMarshaledResult getMB(Ice.Current current) =>
        new Test.Initial_GetMBMarshaledResult(_b1, current);

    public override Task<Test.Initial_GetAMDMBMarshaledResult> getAMDMBAsync(Ice.Current current) =>
        Task.FromResult(new Test.Initial_GetAMDMBMarshaledResult(_b1, current));

    public override Test.M
    opM(Test.M v1, out Test.M v2, Ice.Current current)
    {
        v2 = v1;
        return v1;
    }

    public override Test.F1
    opF1(Test.F1 f11, out Test.F1 f12, Ice.Current current)
    {
        f12 = new Test.F1("F12");
        return f11;
    }

    public override Test.F2Prx
    opF2(Test.F2Prx f21, out Test.F2Prx f22, Ice.Current current)
    {
        f22 = Test.F2PrxHelper.uncheckedCast(current.adapter.getCommunicator().stringToProxy("F22"));
        return f21;
    }

    public override Test.F3
    opF3(Test.F3 f31, out Test.F3 f32, Ice.Current current)
    {
        f32 = new Test.F3(
            new Test.F1("F12"),
            Test.F2PrxHelper.uncheckedCast(current.adapter.getCommunicator().stringToProxy("F22")));
        return f31;
    }

    public override bool
    hasF3(Ice.Current current) => true;

    private readonly Ice.ObjectAdapter _adapter;
    private readonly Test.B _b1;
    private readonly Test.B _b2;
    private readonly Test.C _c;
    private readonly Test.D _d;
}
